<?php
/**
 * @name	User Session
 * @uses	Zend_Session_Namespace
 * 
 * Class holds, processes and stores:
 * - visitor information
 * - user related settings
 * - user specific history
 * - profile information
 * - session data
 * 
 * Class implements proxy design template and proxifyes access to user session namespace 
 * Singleton design pattern allow to avoid session dublicated for current user 
 * 
 * @version		1.1
 * @author		Joseph Chereshnovsky <joseph.chereshnovsky@gmail.com>
 * @copyright	2009
 */
class Wise_User_Session
{
	/**
	 * Holds the singleton instance
	 * 
	 * @staticvar Wise_User_Session
	 */
	private static $user = null;

	/**
	 * Default session namespace
	 * 
	 * You need to set this value before you 
	 * call ::getInstance() for the first time in your script
	 * 
	 * @staticvar Zend_Session_Namespace
	 */
	public static $defaultSessionNamespace = null;
	
	/**
	 * Session namespace object
	 * 
	 * @var Zend_Session_Namespace
	 */
	private $sessionNamespace = null;
	
	/**
	 * List of allowed fields
	 * 
	 * @var array $allowedFields
	 */	
	private $allowedFields = null;

	/**
	 * Initiates the user session
	 */
	private function __construct()
	{
		/**
		 * Convert allowed fields into array
		 * to simplify the fields check operation
		 */
		$this->allowedFields = array(
			  'locale'
			, 'http_referrer'
			, 'ip_address'
			, 'initialized'
			, 'visit_id'
			, 'visited_urls'
			, 'search_phrase'
			, 'source_lang'
			, 'target_lang'
			, 'source_lang_title'
			, 'target_lang_title'
			, 'target_lang_code'
			, 'source_lang_code'
		);
		
		/**
		 * Set default session namespace if provided or create native session namespace 
		 */
		if ((null !== self::$defaultSessionNamespace)
		&&	(self::$defaultSessionNamespace instanceof Zend_Session_Namespace) ) {

			$this->sessionNamespace = self::$defaultSessionNamespace;
			// We can remove old link now
			unset(self::$defaultSessionNamespace);
			
		} else {
			// Create the default session namespace named by current class name
			$this->sessionNamespace = new Zend_Session_Namespace(__CLASS__);
		}

		// get DB
		$db = Zend_Registry::get('Zend_Db');
		
		if (true !== $this->sessionNamespace->initialized) {

			// Session initialization
			Zend_Session::regenerateId();
			$this->sessionNamespace->initialized = true;
			
			// save http referrer
			$this->sessionNamespace->http_referrer = (!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
			
			// user remote ip
			$this->sessionNamespace->ip_address = $_SERVER['REMOTE_ADDR'];
			
			$visits_params = array(
				  'ip_address'		=>	$_SERVER['REMOTE_ADDR']
				, 'http_referrer'	=>	(!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : ''
				, 'created'			=>	new Zend_Db_Expr('NOW()')
				, 'referrer'		=>	'default'
			);
			
			$db->insert('track_visits', $visits_params);
			$visit_id = $db->lastInsertId();

			// seve into session
			$this->sessionNamespace->visit_id = $visit_id;
			
		} else {
			
			$visit_id = $this->sessionNamespace->visit_id; 
			
		}
		
		/**
		 * Track hits
		 */
		$url = $_SERVER['REQUEST_URI'];
		
		// we store visitor's current hits into session to avoid additional database requests
		$url_count = (int) !empty($this->sessionNamespace->visited_urls[$url]['count']) ? $this->sessionNamespace->visited_urls[$url]['count'] : 0;
		
		if (0 == $url_count) {
			
			// create new hit record for current URL
			$hits_params = array(
				  'track_visits_id'	=>	$visit_id
				, 'visited_url'		=>	$url
				, 'count'			=>	1
			);
			
			$db->insert('track_hits', $hits_params);
			
			$data = array(
				  'count'		=> 1
				, 'id'			=> $db->lastInsertId()
				, 'creation'	=> new Zend_Db_Expr('NOW()')
			);
			
			$this->sessionNamespace->visited_urls[$url] = $data;

		} else {
			
			// if URL is already tracked then increase only the hit count value 
			$url_count++;
			$url_track_id = $this->sessionNamespace->visited_urls[$url]['id'];
			
			$data = array(
				'count' => $url_count
			);
			
			$db->update('track_hits', $data, 'id = ' . $url_track_id);
		}
		
	}
	
	/**
	 * Returns singleton object
	 * @param Zend_Session_Namespace
	 * 
	 * NOTE: You need to pass the $sessionNamespace only for first object initialization
	 */
	static public function getInstance()
	{
		/**
		 * Create class instance
		 */
		if (null === self::$user) {
			self::$user = new self;
		}
		
		return self::$user;
	}
	
	/**
	 * Stores the user session for further use
	 */
	private function __desctruct()
	{
		
	}

	/**
	 * Set user related values
	 * 
	 * @param string $name
	 * @param string $value
	 * @return void
	 */
	public function __set($name, $value)
	{
		if (!in_array($name, $this->allowedFields)) {
			return null;
		}
		
		$this->sessionNamespace->$name = $value;
	}
	
	/**
	 * Get user related values
	 * 
	 * @param string $name
	 * @return mixed
	 */
	public function __get($name)
	{
		if (!in_array($name, $this->allowedFields)) {
			return null;
		}
		
		return $this->sessionNamespace->$name;
	}

}